package com.chalk.config.security;

import com.chalk.service.impl.SysUserDetailServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

/**
 * ClassName: AuthorizationServerConfig
 *
 * @author L.G
 * @Description Authorization Server 配置
 * @email lg10000@126.com
 * @date 2018年7月16日 下午3:05:12
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Autowired
    private SysUserDetailServiceImpl sysUserDetailService;

    @Value("${oauth2.client-id}")
    private String clientId;

    @Value("${oauth2.client-secret}")
    private String clientSecret;

    @Value("${oauth2.access-token-validity-seconds}")
    private int accessTokenValiditySeconds;

    @Value("${oauth2.refresh-token-validity-seconds}")
    private int refreshTokenValiditySeconds;

    @Value("${spring.application.name}")
    private String projectName;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        /* 配置客户端,用于password认证 */
        clients.inMemory()
                .withClient(clientId)
                .authorizedGrantTypes("password", "refresh_token")
                .authorities("oauth2")
                .scopes("read", "write")
                .secret(SecurityPasswordUtil.BCRYPT + SecurityPasswordUtil.encrypt(clientSecret))
                .accessTokenValiditySeconds(accessTokenValiditySeconds)
                .refreshTokenValiditySeconds(refreshTokenValiditySeconds);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        CustomRedisTokenStore customRedisTokenStore = new CustomRedisTokenStore(redisConnectionFactory);
        customRedisTokenStore.setPrefix(projectName.replace("/", "") + ":");
        endpoints.tokenStore(customRedisTokenStore)
                .authenticationManager(authenticationManager)
                .userDetailsService(sysUserDetailService)
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        /* 允许表单认证  */
        oauthServer.allowFormAuthenticationForClients();
    }

}
